package com.css.fghs.controller;


import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.css.constant.Result;
import com.css.constant.SsoConstants;
import com.css.exception.ServiceException;
import com.css.fghs.entity.domain.FgjyYhzxYhxxbDO;
import com.css.fghs.entity.vo.LoginReqVO;
import com.css.fghs.entity.vo.LoginRespVO;
import com.css.fghs.entity.vo.RegisterReqVO;
import com.css.fghs.service.FgjyYhzxYhxxbService;
import com.css.fghs.service.LoginService;
import com.css.util.GyUtils;
import com.css.util.RedisUtils;
import com.css.util.ServletUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

@Api(tags = "登录注册")
@Slf4j
@RestController
@RequestMapping("/mh")
public class LoginController {

    @Resource
    private LoginService loginService;
    @Resource
    private FgjyYhzxYhxxbService yhxxbService;
    @Resource
    private RedisTemplate<String, String> redisTemplate;

    @PermitAll
    @GetMapping("/sms/code")
    public Result sendSmsCode(@RequestParam String phone) {
        //生成随机验证码
        String code = RandomStringUtils.randomNumeric(6);

        //存缓存，5分钟过期
        String redisKey = "SMS_CODE_" + phone;
        redisTemplate.opsForValue().set(redisKey, code, 5, TimeUnit.MINUTES);

        //todo 发送短信
        CompletableFuture.runAsync(() -> {
            try {
//                loginService.sendSms(phone, code);
                log.info("短信发送成功，手机号: {}, 验证码: {}", phone, code);
            } catch (Exception e) {
                log.error("短信发送失败，手机号: {}", phone, e);
            }
        });

        return Result.ok(code);
    }

    @PermitAll
    @PostMapping("/register")
    public Result register(@RequestBody @Valid RegisterReqVO reqVO) {
        if (GyUtils.isNull(reqVO.getPassword())) {
            throw new ServiceException("密码不能为空");
        }
        String phone = reqVO.getPhone();
        String sms = reqVO.getSms();
        String redisKey = "SMS_CODE_" + phone;
        String smsCode = redisTemplate.opsForValue().get(redisKey);
        LambdaQueryWrapper<FgjyYhzxYhxxbDO> query = new LambdaQueryWrapper<>();
        query.eq(FgjyYhzxYhxxbDO::getSjhm1,reqVO.getPhone());
        FgjyYhzxYhxxbDO yhxxbDO = yhxxbService.getOne(query);
        if (GyUtils.isNotNull(yhxxbDO)) {
            throw new ServiceException("该手机号已注册");
        }
        if (GyUtils.isNull(smsCode)) {
            throw new ServiceException("验证码已过期，请重新获取");
        }
        if (!smsCode.equals(sms)) {
            throw new ServiceException("验证码错误");
        }
        loginService.register(reqVO);
        redisTemplate.delete(redisKey);
        return Result.ok();
    }

    @PostMapping("/login")
    @PermitAll
    @ApiOperation(value = "使用手机号密码登录")
    public Result<LoginRespVO> login(@RequestBody @Valid LoginReqVO reqVO, HttpServletRequest request) throws Exception {
        AtomicReference<LoginRespVO> login = new AtomicReference<>(new LoginRespVO());
        try {
            //登录逻辑
            login.set(loginService.login(reqVO));
            //回写cookie
            final HttpServletResponse response = ServletUtil.getResponse();
            final Cookie cookie = new Cookie(SsoConstants.COOKIE_TOKEN_KEY, login.get().getAccessToken());
            cookie.setPath(SsoConstants.COOKIE_PATH);
            cookie.setHttpOnly(true);
            cookie.setMaxAge(7200);
            response.addCookie(cookie);
            return Result.ok(login.get());
        } catch (Exception e) {
            throw new ServiceException(e.getMessage());
        }
    }

    @PostMapping("/smsLogin")
    @PermitAll
    @ApiOperation(value = "使用手机号验证码登录")
    public Result<LoginRespVO> smsLogin(@RequestBody @Valid RegisterReqVO reqVO) throws Exception {
        AtomicReference<LoginRespVO> login = new AtomicReference<>(new LoginRespVO());
        String phone = reqVO.getPhone();
        String sms = reqVO.getSms();
        String redisKey = "SMS_CODE_" + phone;
        String smsCode = redisTemplate.opsForValue().get(redisKey);
        LambdaQueryWrapper<FgjyYhzxYhxxbDO> query = new LambdaQueryWrapper<>();
        query.eq(FgjyYhzxYhxxbDO::getSjhm1,reqVO.getPhone()).eq(FgjyYhzxYhxxbDO::getYxbz,"Y");
        FgjyYhzxYhxxbDO yhxxbDO = yhxxbService.getOne(query);
        if (GyUtils.isNull(yhxxbDO)) {
            throw new ServiceException("账户不存在,请先注册账户");
        }
        if (GyUtils.isNull(smsCode)) {
            throw new ServiceException("验证码已过期，请重新获取");
        }
        if (!smsCode.equals(sms)) {
            throw new ServiceException("验证码错误");
        }
        try {
            //登录逻辑
            login.set(loginService.smsLogin(reqVO));
            //回写cookie
            final HttpServletResponse response = ServletUtil.getResponse();
            final Cookie cookie = new Cookie(SsoConstants.COOKIE_TOKEN_KEY, login.get().getAccessToken());
            cookie.setPath(SsoConstants.COOKIE_PATH);
            cookie.setHttpOnly(true);
            //cookie.setMaxAge(-1);
            response.addCookie(cookie);
            return Result.ok(login.get());
        } catch (Exception e) {
            throw new ServiceException(e.getMessage());
        }
    }

    @PostMapping("/logout")
    @PermitAll
    @ApiOperation(value = "登出系统")
    public Result logout(HttpServletRequest request) {
        final String token = request.getHeader(SsoConstants.COOKIE_TOKEN_KEY);
//        String token = "";
//        Cookie[] cookies = request.getCookies();
//        List<Cookie> collect = Arrays.stream(cookies).filter(v -> v.getName().equals(SsoConstants.COOKIE_TOKEN_KEY)).collect(Collectors.toList());
//        if (!GyUtils.isNull(collect)){
//            token = collect.get(0).getValue();
//        }
        if (StrUtil.isNotBlank(token)) {
            RedisUtils.delete(token);
            final HttpServletResponse response = ServletUtil.getResponse();
            final Cookie cookie = new Cookie(SsoConstants.COOKIE_TOKEN_KEY,token);
            cookie.setPath(SsoConstants.COOKIE_PATH);
            cookie.setHttpOnly(true);
            cookie.setMaxAge(0);
            response.addCookie(cookie);
        }
        return Result.ok("success");
    }


    @PostMapping("/resetPassword")
    @ApiOperation(value = "忘记密码")
    public Result resetPassword(@RequestBody @Valid LoginReqVO reqVO) {
        String phone = reqVO.getPhone();
        String sms = reqVO.getSms();
        String redisKey = "SMS_CODE_" + phone;
        String smsCode = redisTemplate.opsForValue().get(redisKey);
        LambdaQueryWrapper<FgjyYhzxYhxxbDO> query = new LambdaQueryWrapper<>();
        query.eq(FgjyYhzxYhxxbDO::getSjhm1,reqVO.getPhone());
        FgjyYhzxYhxxbDO yhxxbDO = yhxxbService.getOne(query);
        if (GyUtils.isNull(yhxxbDO)) {
            throw new ServiceException("用户不存在");
        }
        if (GyUtils.isNull(sms)) {
            throw new ServiceException("验证码不能为空");
        }
        if (GyUtils.isNull(smsCode)) {
            throw new ServiceException("验证码已过期，请重新获取");
        }
        if (!smsCode.equals(sms)) {
            throw new ServiceException("验证码错误");
        }
       return loginService.resetPassword(reqVO);
    }
}
